<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>commander</title>
		<script src="static/js/jquery-1.10.2.min.js"></script>
		<style>
			#photo{
				float:right;
				width:512px;
				height:256px;
				border:1px solid black;
			}
			#map{
				margin:0 auto;			
				height:100%;
			}
			#map:hover{
				cursor: crosshair;
			}
			#obstacles{
				margin:0 auto;
				position:absolute;
				left:0;
				right:0;
				top:0;
				bottom:0;
				z-index:-1;
			}
			#map-wrapper{
				width:100%;
				height:100%;
				position:relative;
			}
			#map-container{
				position:absolute;
				top:0;
				bottom:0;
				left:0;
				right:0;
				background:#D8D8D8;
				z-index:-1;
				padding-left:232px;
				padding-right:232px;
				text-align:center;
			}

			#battery{
				height:1.3em;
				width:200px;
				background-color:#777;
				margin:0 auto;
				position:relative;
			}
			#battery-level{
				height:100%;
				width:0%;
				background-color:green;
			}
			.disconnected #battery-level{
				background-color: grey;
			}
			#battery-percent{
				position:absolute;
				left:0;
				right:0;
				bottom:0;
				top:0;
				color:white;
				font-weight:bold;
			}
			fieldset{
				position:relative;
			}
			html,body{
				overflow:hidden;
				margin:0;
			}
			form{
				background:white;
				top: 0;
				bottom:0;
				width: 232px;
				left:0;
				position:absolute;
				margin:0;
				text-align:center;
			}
			
			body.noscroll{
				position:fixed;
				overflow:hidden;
			}
			#photos{
				position:absolute;
				right:0;
				top:0;
				bottom:0;
				background:white;
				float:right;
				width:232px;
				overflow-y:auto;
			}
			#photos li{
				list-style-type:none;
			}
			#search{
				background:#3C3;
				width: 5em;
				height:2em;
				font-size:40px;
				color: white;
				margin-bottom: 10px;
			}
			#search:hover{
				background-color: #3F3;
			}
			.disconnected #search{
				background-color: grey;
			}
			#music{
				background:#3C9;
				width: 5em;
				height:2em;
				font-size:40px;
				color: white;
			}
			#music:hover{
				background-color: #3F9;
			}
			.disconnected #music{
				background-color: grey;
			}
			#templates{
				display:none;
			}
			#viewer{
				display:none;
				position:fixed;
				top:60%;
				left:45%;
				height:480px;
				width:640px;
				margin-left:-240px;
				margin-top:-320px;
				z-index:1;
			}
			
		</style>
	</head>
	<body class="disconnected">
		<img id="viewer" href="#" title="click to close">
		<form method="post">
			<img id="arrows" usemap="#move" src="static/css/MoveArrows.png" alt="Move Arrows">
			<map name="move">
				<area shape="poly" coords="116,5,148,53,131,53,131,121,102,121,101,53,85,53" href="#" title="Move forwards" name="forward"> 
				<area shape="poly" coords="102,220,130,220,130,288,148,288,117,335,85,288,101,288" href="#" title="Move backwards" name="backward"> 
				<area shape="circle" coords="115,170,40" href="#" alt="Stop" name="stop"> 
				<area shape="poly" coords="183,84,194,97,202,112,209,128,214,146,216,162,216,180,214,197,209,213,201,231,224,245,166,271,154,208,179,219,188,203,194,184,194,166,192,148,184,128,177,113,165,98" href="#" title="Turn right" name="right"> 
			       <area shape="poly" coords="47,84,36,97,28,112,21,128,16,146,14,162,14,180,16,197,21,213,29,231,6,245,64,271,76,208,51,219,42,203,36,184,36,166,38,148,46,128,53,113,65,98" href="#" title="Turn left" name="left"> 
			</map>
			<!--<a id="photo-link" target="_blank"><img id="photo" alt="no image"></a>-->
			<!--<fieldset>
				<legend>motor controls</legend>
				<button type="submit" name="do" value="stop">stop</button>
				<br>
				<button type="submit" name="do" value="backward">backward</button>
				<button type="submit" name="do" value="forward">forward</button>
				<br>
				<button type="submit" name="do" value="left">left</button>
				<button type="submit" name="do" value="right">right</button>
			</fieldset>
			<fieldset>
				<legend>high-level controls</legend>			
			</fieldset>
			<fieldset>
				<legend>sensors</legend>
				<label for="battery">battery</label>
				<input id="battery">
			</fieldset>-->
			
			<!--<button type="submit" name="do" value="search" id="search" title="Take a close photo">Examine</button>-->
			<button type="submit" name="do" value="music" id="music" title="Beep">Beep</button>
			<input type="image" id="camera" name="go" value="photo" src="static/css/camera.png" width="150" height="100" title="Take a picture">
			<div id="battery">
				<div id="battery-level"></div>
				<div id="battery-percent">
					Loading
				</div>
			</div>
		</form>
		<div id="map-container">
			<div id="map-wrapper">
				<canvas id="map" width="800" height="800">
					cannot show map
				</canvas>
				<img id="obstacles" height="100%">
			</div>
		</div>
		<div id="photos">
			<ul id="photo-list"></ul>
		</div>
		<div id="templates">
			<li class="photo-item">
				<a target="_blank" title="open in new window"><img width="160" height="128"></a>
			</li>
		</div>
		<script>
			$(function(){
				var px_per_m=100;
				function fillCircle(gfx,pos,r,c){
					var oldc = gfx.fillStyle;
					gfx.fillStyle=c;
					gfx.arc(pos[0],pos[1],r,0,2*Math.PI);
					gfx.fill();
					gfx.fillStyle = oldc;
					gfx.beginPath();
				}
				function fillTile(gfx,pos,r,c){
					var oldc=gfx.fillStyle;
					gfx.fillStyle=c;
					gfx.rect(pos[0],pos[1],r,r);
					gfx.fill();
					gfx.fillStyle = oldc;
					gfx.beginPath();
				
				}
				function updateMap(pos,pTrail,trail){
					var c=document.getElementById("map");
					var gr=c.getContext("2d");
					gr.lineWidth=0.03;

					gr.save();
					gr.setTransform(1,0,0,1,0,0);
					gr.clearRect(0,0,c.width,c.height);
					gr.restore();

					gr.save()
					gr.translate(c.width/2,c.height/2);
					gr.scale(px_per_m,px_per_m);//100 px/m
					pos[1]*=-1;
					
					var gridres=100;
					
					//console.log(1.23);
					var cp = "#0000FF";
					var pp = "#00AA00";
					var fp = "#D07000";
					var op = "#000000"; //don't change this colour
					
					//pos=[x,y] in meters: position[0]=x, position[1]=y
					//pTrail=[[left_arclength,right_arclength],...]
					//trail=[[left_arclength,right_arclength],...]
					//0<=obstacles[i][j]<=1
					
					//pos=[0,0,Math.PI*0.25];
					//pTrail=[[0.52,0.52],[0.52,0.33],[0.72,0.55],[0.55,0.72],[0.55,0.6],[0.52,0.52]];
					//trail=[[380,380]]
					
					var tx=0;
					var ty=0;
					var x=pos[0];
					var y=pos[1];
					var cx = 0;
					var cy = 0;
					var rb = 0;
					var tt1 = 0;
					var tt2 = 0;
					var r = 0.07125;
					var t2 = pos[2];
					var t1=0;
					
					var a1=0;
					var a2=0;
					
					for (var i=0;i<pTrail.length;i++){ 
						//var tx=0;
						//var ty=0;
						
						al = pTrail[i][0];
						ar = pTrail[i][1];
						
						if (i>0){
							x=tx;
							y=ty;
							t2=t1;
						}
						
						gr.beginPath();
						
						if ((al-ar)==0){
							tx=x-(al*Math.cos(t2)); //updating the position of the end of the curve
							ty=y+(al*Math.sin(t2));
							t1=t2;
							gr.moveTo(tx,ty);
							gr.lineTo(x,y);
						}
						else if(al+ar==0){
							console.log(ar,r,ar/r);
							t1=t2+ar/l;
							tx=x;
							ty=y;
						}
						else{
							if (al>ar){
								t1=((2*r*t2)+al-ar)/(2*r);
							
								cx = x+(r*(al+ar)*Math.sin(t2))/Math.abs((al-ar));
								cy = y+(r*(al+ar)*Math.cos(t2))/Math.abs((al-ar));
								rb=(r*(al+ar))/Math.abs((al-ar));
								tt1=(1.5*Math.PI)-((2*r*t2)+al-ar)/(2*r);
								tt2=(1.5*Math.PI)-t2;
								
								tx=cx-(rb*Math.sin(t1));
								ty=cy-(rb*Math.cos(t1));
								
								gr.arc(cx,cy,rb,tt1,tt2);
							}
							
							
							else{
								t1=((2*r*t2)+al-ar)/(2*r);
							
								cx = x-(r*(al+ar)*Math.sin(t2))/Math.abs((al-ar));
								cy = y-(r*(al+ar)*Math.cos(t2))/Math.abs((al-ar));
								rb=(r*(al+ar))/Math.abs((al-ar));
								tt1=(0.5*Math.PI)-((2*r*t2)+al-ar)/(2*r);
								tt2=(0.5*Math.PI)-t2;
								
								tx=cx+(rb*Math.sin(t1));
								ty=cy+(rb*Math.cos(t1));
								
								gr.arc(cx,cy,rb,tt1,tt2,1);
							}
							
							
							
							
							
							//gr.arc(cx,cy,rb,tt1,tt2); //1 is CCW
						}
						
						
						gr.stroke();
						
						gr.beginPath();
						//gr.arc(tx,ty,r,0,2*Math.PI);
						//fillCircle(gr,[tx,ty],.05,pp);
						//gr.stroke();
						//
						//gr.beginPath();
						//gr.arc(x,y,r,0,2*Math.PI);
						//fillCircle(gr,[x,y],.05,pp);
						//gr.stroke();
						
					}		
					
					//for (var i=0;i<trail.length;i++){ 
					//	fillCircle(gr,trail[i],3,fp);
					//}	
					
					fillCircle(gr,pos,.05,cp);
					
					
					gr.restore();
				}
				(function update(){
					$.post("/battery")
						.done(function(battery){
							$("#battery-percent").text("Battery Life: "+(battery*100).toFixed(1)+"%");
							$("#battery-level").css({width:battery*100+"%"});
						}).always(function(){
							setTimeout(update,10000);
						});
				})();
				$("form [name=do]").click(function(e){
					e.preventDefault();
					$.post("/"+$(this).val());
				});
				$("map[name=move] area[name]").click(function(e){
					e.preventDefault();
					$.post("/"+$(this).attr("name"));
				});
				$("input[name=go]").click(function(e){
					e.preventDefault();
					$.post("/"+$(this).val())
						.done(function(data){
							$("#photo").attr("alt",data.path).attr("src",data.path);
							$("#photo-link").attr("href",data.path);
						});
				});
				function photoItem(photo){
					var $elt=$("#templates>.photo-item").clone().prependTo("#photo-list");
					$elt.find("a").click(function(e){
						e.preventDefault();
						$("#viewer").attr("src",photo.path).show("fast");
					}).find("img").attr("src",photo.path);
					return $elt;
				}
				$("#viewer").click(function(){
					$(this).hide("fast");
				});
				function showPhoto(photo){
					console.log("showing thumbnail",photo);
					var transform="rotate("+(photo.theta-Math.PI/2)+"grad)";
					$("<img>")
						.addClass("thumb")
						.attr("src",photo.path)
						.css({
							left:400+photo.x+"px",
							top:400-photo.y+"px",
							transform:transform,
							MsTransform:transform,
							WebkitTransform:transform,
						})
						.appendTo("#map-container");
				}

				$(document).ready(function () {
					$('body').on('keydown keyup',function(e){
      						var start = e.type=="keydown" ? 'yes' : 'no' ;
						if(start=='no'){
							$.post("/stop");
						}
						else{
      							if(e.which==37){
          							$.post("/left");
							}
							if(e.which==38){
          							$.post("/forward");  
							}
							if(e.which==39){
          							$.post("/right"); 
							}
							if(e.which==40){
          							$.post("/backward");
							}
						}
 					});
				});

				var photos=[],state={},trail=[];
				$(document)
					.on("connected",function(e,connected){
						$("body").removeClass("connected disconnected").addClass((connected?"":"dis")+"connected");
						$("input").prop("disabled",!connected);
						if(!connected)
							$("battery-level").text("not connected");
					}).trigger("connected",false).on("photo",function(e,photo){
						var $elt=photoItem(photo);
						showPhoto(photo);
						return $elt;
					}).on("trail",function(e,data){
						trail.push(data);
					}).on("where trail",function(){
						if(state.where)
							;//updateMap(state.where.slice(0),trail.slice(0).reverse(),[]);
					}).on("map_path",function(e,data){
						$("#obstacles").attr("src",data);
					}).keyup(function(e){
						if(e.which==32)
							$.post("/photo");
					});
				$("#camera").click(function(e){
					$.post("/photo");
				});
				$("#map").click(function(e){
					var pageX=e.clientX+document.body.scrollLeft,pageY=e.clientY+document.body.scrollTop,ofs=$(this).offset();
					e.preventDefault();
					$.post("/set_target?x="+(pageX-ofs.left-400)/px_per_m+"&y="+(400-(pageY-ofs.top))/px_per_m);
				});
				var params="";
				(function subscribe(){
					$.ajax({
						url:"/subscribe"+params,
						type:"POST",
						timeout:30000,
						dataType:"json",
					}).fail(function(e){
						if(e.status!=0){
							setTimeout(subscribe,1000);
							return;
						}
						$(document).trigger("connected",false);
						(function reconnect(){
							$.ajax({
								url:"/subscribe",
								type:"POST",
								timeout:10000,//should be immediate
								dataType:"json",
							}).success(function(){
								$(document).trigger("connected",true);
								subscribe();
							}).fail(function(){
								setTimeout(reconnect,1000);
							});
						})();
					}).done(function(data){
						if(!params){//first one; we're done loading the main ui
							$.post("/history?key=photo&t="+data.t)
								.done(function(photos){
									$(photos.reverse()).map(function(i,e){
										var $elt=photoItem(e[1]);
										showPhoto(e[1]);
										return $elt[0];
									}).appendTo("#photo-list");
								});
							$.post("/history?key=trail&t="+data.t)
								.done(function(prefix){
									for(var i=0;i<prefix.length;++i)
										prefix[i]=prefix[i][1];
									trail=prefix.concat(trail);
								});
						}
						params="?t="+data.t;
						for(var a=data.deltas,i=0;i<a.length;++i){
							console.log("%o: %o at %o",a[i][0],a[i][1],a[i][2]);
							state[a[i][0]]=a[i][1];
							var e=$.Event(a[i][0]);
							e.timeStamp=a[i][2]*1000;
							//try{
								$(document).trigger(e,[a[i][1]]);
							//}catch(e){
							//	console.error(e);
							//}
						}
						subscribe();
					});
				})();
			});
		</script>
			
	</body>
</html>
